package cn.b.sky.mes.cm.service.impl;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import cn.b.sky.mes.cm.dao.BOMComponentDao;
import cn.b.sky.mes.cm.dao.MaterialDao;
import cn.b.sky.mes.cm.model.BOMComponent;
import cn.b.sky.mes.cm.model.MateriaProcessAssign;
import cn.b.sky.mes.cm.model.Material;
import cn.b.sky.mes.cm.model.condition.MaterialCondition;
import cn.b.sky.mes.cm.service.MaterialService;
import cn.b.sky.common.exception.ImeException;
import cn.b.sky.common.model.BatchJobReport;
import cn.b.sky.common.utils.DatabaseUtils;
import cn.b.sky.common.utils.DateUtils;
import cn.b.sky.i18n.utils.LocaleResourceBundle;
import cn.b.sky.user.SecurityContextUtil;

/**
 * 
 * <strong>Title : MaterialServiceImpl.java<br>
 * </strong> <strong>Package : cn.b.sky.mes.cm.service.impl<br>
 * </strong> <strong>Description : </strong>物料主数据业务实现类<br>
 * <strong>Create on : 2015-9-30 下午02:02:28<br>
 * </strong>
 * <p>
 * 
 * @author zhaoxin01<br>
 * @version <strong>v1.0.0</strong><br>
 * <br>
 *          <strong>修改历史:</strong><br>
 *          修改人 | 修改日期 | 修改描述<br>
 *          -------------------------------------------<br>
 * <br>
 * <br>
 */
@Service("materialService")
public class MaterialServiceImpl implements MaterialService {

  private static final Logger LOGGER = LoggerFactory.getLogger(MaterialServiceImpl.class);

  @Resource
  MaterialDao materialDao;

  @Resource
  BOMComponentDao bOMComponentDao;

  @Override
  public List<Material> selectMaterialList(MaterialCondition materialCondition) {
    return materialDao.selectMaterialList(materialCondition);
  }

  @Override
  public int selectMaterialListCount(MaterialCondition materialCondition) {
    return materialDao.selectMaterialListCount(materialCondition);
  }

  @Override
  public Material selectMaterial(String siteCode, String materialCode) {

    return materialDao.selectMaterial(siteCode, materialCode);
  }

  @Override
  public List<MateriaProcessAssign> selectProcessByMaterial(String siteCode, String materialCode) {
    return materialDao.selectProcessByMaterial(siteCode, materialCode, new Date());
  }

  @Override
  public void insertMaterial(Material material) {
    materialDao.insertMaterial(material);
    if (material.getProcessList() != null) {
      for (MateriaProcessAssign mp : material.getProcessList()) {
        materialDao.insertMateriaProcessAssign(mp);
      }
    }
  }

  @Override
  public void updateMaterial(Material material) throws ImeException {
    if (!StringUtils.isEmpty(material.getBomCode())
        && isBomComponent(material.getSiteCode(), material.getBomCode(), material.getMaterialCode())) {
      throw ImeException.newException("bomCycleError.M");
    }
    materialDao.updateMaterial(material);
    materialDao.deleteMateriaProcessAssign(material.getSiteCode(), material.getMaterialCode());
    if (material.getProcessList() != null) {
      for (MateriaProcessAssign mp : material.getProcessList()) {
        if (materialDao.slelectMaterialIsInProcess(mp) > 0) {
          String[] arr = new String[1];
          arr[0] = mp.getProcessCode();
          throw ImeException.newException("materiaProcessAssignError.M", arr);
        }
        materialDao.insertMateriaProcessAssign(mp);
      }
    }
  }

  /**
   * 
   * <strong>Title : isBomComponent<br></strong>
   * <strong>Description : </strong>查找BOM树中是否包含此物料<br> 
   * <strong>Create on : 2016-1-19 下午02:41:31<br></strong>
   * <p>
   * @param siteCode
   * @param bomCode
   * @param materialCode
   * @return
   * boolean
   * @throws 
   * @author zhaoxin01<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  private boolean isBomComponent(String siteCode, String bomCode, String materialCode) {
    List<BOMComponent> bcs = bOMComponentDao.selectComponents(bomCode, siteCode);
    return findComponent(bcs, materialCode);
  }

  private boolean findComponent(List<BOMComponent> bcs, String materialCode) {
    boolean result = false;
    for (BOMComponent bc : bcs) {
      if (bc.getComponentCode().equals(materialCode)) {
        return true;
      } else {
        Material m = materialDao.selectMaterial(bc.getSiteCode(), bc.getComponentCode());
        if (!StringUtils.isEmpty(m.getBomCode())) {
          List<BOMComponent> bcList = bOMComponentDao.selectComponents(m.getBomCode(), m.getSiteCode());
          result = findComponent(bcList, materialCode);
          if (result) {
            return result;
          }
        }
      }
    }
    return result;
  }

  @Override
  public BatchJobReport deleteMaterial(String siteCode, String materialCode) {
    String cause = "";
    Boolean success = true;
    try {
      materialDao.deleteMateriaProcessAssign(siteCode, materialCode);
      materialDao.deleteMaterial(siteCode, materialCode);
    } catch (Exception e) {
      LOGGER.error("{}", e);
      TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
      if (DatabaseUtils.isConstraintsError( e.getMessage())) {
        // 外键删除已存在提示
        cause = LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),SecurityContextUtil.getLanguageCode(),
            "dataBaseOperationPkFail.M")
            + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),SecurityContextUtil.getLanguageCode(), "notDelete.M");
      } else {
        cause = e.getMessage();
      }
      success = false;
    }
    return new BatchJobReport(materialCode, cause, success, SecurityContextUtil.getLanguageCode(),SecurityContextUtil.getSiteCode());
  }

  @Override
  public List<MateriaProcessAssign> selectLastProcessByMaterial(String siteCode, String materialCode) {
    if (StringUtils.isBlank(siteCode) || StringUtils.isBlank(materialCode)) {
      return null;
    }
    Material materia = this.selectMaterial(siteCode, materialCode);
    String currentTime = DateUtils.getDateUtils().getDateStr(new Date());
    List<MateriaProcessAssign> process = materialDao.selectLastProcessByMaterial(siteCode, materialCode, currentTime);
    // 设置默认值
    if (materia != null && process != null) {
      for (MateriaProcessAssign mpa : process) {
        if (mpa.getProcessCode().equals(materia.getProcessCode())) {
          mpa.setIsDefault(1);
          break;
        } else {
          continue;
        }
      }
    }
    return process;
  }

  @Override
  public List<Material> selectMaterialSuggests(MaterialCondition material) {
    return materialDao.selectMaterialSuggests(material);
  }

}
